#include "database_system.h"
#include <iostream>
#include "db_manager/utils/string_utils.hpp"
int main()
{
    DatabaseSystem db;
    std::cout << "MiniDB CLI (type 'quit;' to exit)\n";

    std::string sql_buffer; // 用于拼接跨行SQL语句

    while (true)
    {
        // 根据缓冲区是否为空，打印不同的提示符
        if (sql_buffer.empty())
        {
            std::cout << "MiniDB > ";
        }
        else
        {
            // 如果缓冲区有内容，说明是多行输入的中间行
            std::cout << "    -> ";
        }

        std::string line_part;
        // 先读取一整行，这样可以保留行内编辑功能
        if (!std::getline(std::cin, line_part))
        {
            // 如果读取失败 (例如遇到 EOF, Ctrl+D/Ctrl+Z)，就退出
            break;
        }
        // 在将行加入缓冲区之前，处理行内注释
        // 查找 '--' 注释
        size_t comment_pos_dash = line_part.find("--");
        if (comment_pos_dash != std::string::npos)
        {
            line_part = line_part.substr(0, comment_pos_dash);
        }

        // 查找 '#' 注释
        size_t comment_pos_hash = line_part.find('#');
        if (comment_pos_hash != std::string::npos)
        {
            line_part = line_part.substr(0, comment_pos_hash);
        }

        // 如果处理完注释后行不为空，则加入缓冲区
        if (!line_part.empty())
        {
            // 去除处理后行前后的空白
            line_part.erase(0, line_part.find_first_not_of(" \t\n\r"));
            line_part.erase(line_part.find_last_not_of(" \t\n\r") + 1);

            // 只有在确实有内容时才加入
            if (!line_part.empty())
            {
                if (!sql_buffer.empty())
                {
                    sql_buffer += " "; // 在语句部分之间加空格
                }
                sql_buffer += line_part;
            }
        }

        // 查找缓冲区中是否有分号
        size_t semi_pos = sql_buffer.find(';');

        // 只要缓冲区中包含分号，就循环处理所有完整的语句
        while (semi_pos != std::string::npos)
        {
            // 提取第一条完整的SQL语句 (从开始到第一个分号)
            std::string single_sql = sql_buffer.substr(0, semi_pos + 1);

            // 从缓冲区中移除已提取的语句和分号
            // +1 是为了同时移除分号本身
            sql_buffer.erase(0, semi_pos + 1);

            // 去除语句前后的空白字符
            // (这是一个简单的实现，可以替换为更健壮的 trim 函数)
            single_sql.erase(0, single_sql.find_first_not_of(" \t\n\r"));
            single_sql.erase(single_sql.find_last_not_of(" \t\n\r") + 1);

            if (single_sql.empty())
            {
                // 如果分号前是空的，继续下一次循环
                semi_pos = sql_buffer.find(';');
                continue;
            }

            // 检查退出命令
            if (single_sql == "quit")
            {
                std::cout << "MiniDB exited." << std::endl;
                return 0; // 直接退出程序
            }

            // --- 执行SQL并打印结果 ---
            std::cout << "Executing: " << single_sql << std::endl; // 回显执行的SQL
            auto result = db.execute_sql(single_sql);

            if (result.status == "success")
            {
                if (result.type == QueryType::SELECT)
                {
                    std::cout << result.message << std::endl;
                    std::cout << "-------------------------------------------------------------------" << std::endl;
                    for (const auto &col : result.columns)
                        std::cout << col << "\t";
                    std::cout << std::endl;
                    for (const auto &row : result.rows)
                    {
                        for (const auto &val : row)
                        {
                            std::cout << "|";
                            if (!val.has_value())
                            {
                                std::cout << "NULL" << "\t";
                            }
                            else
                            {
                                // 注意：直接用 visit 打印，而不是 toJson，可以避免字符串被加上多余的引号
                                std::visit([](auto &&arg)
                                           { std::cout << toJson(arg); }, val.value());
                                std::cout << "\t";
                            }
                        }
                        std::cout << std::endl;
                    }
                }
                else if (result.type == QueryType::SHOW_TABLES)
                {
                    std::cout << result.message << std::endl;
                    std::cout << "-------------------------------------------------------------------" << std::endl;
                    for (const auto &[schema_name, columns] : result.schemas)
                    {
                        std::cout << "\nTable: " << schema_name << std::endl;
                        std::cout << "--------------------------------------------" << std::endl;
                        for (const auto &col : columns)
                        {
                            std::cout << "  " << col.name << " " << col.type << (toUpperCase(col.type) == "VARCHAR" || toUpperCase(col.type) == "CHAR" ? "(" + std::to_string(col.length) + ")" : "") << " " << (col.nullable ? "NULL" : "NOT NULL") << (col.primary ? " PRIMARY KEY" : "") << (col.unique ? " UNIQUE" : "") << (col.auto_increment ? " AUTO_INCREMENT" : "") << (col.default_value.has_value() ? " DEFAULT '" + col.default_value.value() + "'" : "") << (col.comment.empty() ? "" : " COMMENT '" + col.comment + "'") << std::endl;
                        }
                    }
                    std::cout << std::endl;
                }
                else if (result.type == QueryType::SHOW_INDICES)
                {
                    std::cout << result.message << std::endl;
                    std::cout << "-------------------------------------------------------------------" << std::endl;
                    for (const auto &index : result.indexes)
                    {
                        std::cout << "\nIndex: " << index.index_name << std::endl;
                        std::cout << "--------------------------------------------" << std::endl;
                        std::cout << "  Columns: ";
                        for (size_t i = 0; i < index.columns.size(); ++i)
                        {
                            std::cout << index.columns[i] << (i < index.columns.size() - 1 ? ", " : "");
                        }
                        std::cout << "\n  Unique: " << (index.is_unique ? "Yes" : "No") << std::endl;
                    }
                    std::cout << std::endl;
                }
                else
                {
                    // 打印CREATE/INSERT/UPDATE/DELETE等操作的结果
                    std::cout << result.message << std::endl;
                }
            }
            else
            {
                // 打印错误
                std::cout << "Error: [" << result.error_type << "] " << result.message << std::endl;
            }

            // 检查缓冲区中是否还有下一个分号
            semi_pos = sql_buffer.find(';');
        }
    }

    std::cout << "MiniDB exited." << std::endl;
    return 0;
}